﻿/** \file
* \$Rev: 183 $
* 
* \$Date: 2010-04-14 00:34:38 +0000 (Wed, 14 Apr 2010) $
*
* \$URL: http://chorus-twitter.googlecode.com/svn/trunk/src/gui/MessageRow.cs $
*/

using System;
using System.Drawing;
using System.Windows.Forms;
using chorus.utils;

namespace chorus.gui
{
	/// <summary>
	/// A single message item in a view.
	/// </summary>
	public partial class MessageRow : SplitContainer
	{
		/// <summary>The "from" picture form.</summary>
		ProfilePicForm pic1;
		/// <summary>The "to" picture form.</summary>
		ProfilePicForm pic2;
		/// <summary>The "from" thumb box.</summary>
		PictureBox thumb1;
		/// <summary>The "to" thumb box.</summary>
		PictureBox thumb2;
		/// <summary>The message text containing links.</summary>
		LinkedRTF rtf;
		/// <summary>The message associated with this row.</summary>
		twitter.Message msg;
		/// <summary>Whether there are both "from" and "to" images.</summary>
		bool dual;
		/// <summary>Whether the row is expanded or not.</summary>
		bool hovered;

		/// <summary>The constructor.</summary>
		/// <param name="msg">The message associated with this row.</param>
		public MessageRow(twitter.Message msg)
		{
			this.msg = msg;
			dual = msg.To != null;

			InitializeComponent();

			rtf = new LinkedRTF(msg);
			rtf.Resize += new EventHandler(rtf_Resize);
			rtf.MouseEnter += new EventHandler(HoverOn);
			rtf.MouseLeave += new EventHandler(HoverOff);
			Panel2.Controls.Add(rtf);

			rtf_Resize(null, null);

			if (msg.From != null)
				msg.From.LoadImageAsync(false, ImageAsync_FromThumb);
			if (msg.To != null)
				msg.To.LoadImageAsync(false, ImageAsync_ToThumb);
		}

		/// <summary>Fired when the RTF text is resized.</summary>
		/// <param name="sender">The event sender.</param>
		/// <param name="e">The event parameters.</param>
		void rtf_Resize(object sender, EventArgs e)
		{
			Height = Math.Max(rtf.Height, 48);
		}

		/// <summary>A callback to receive the "from" small image.</summary>
		/// <param name="image">The received image.</param>
		void ImageAsync_FromThumb(Image image)
		{
			Utils.InvokeControl(this, delegate()
			{
				thumb1 = new PictureBox();
				thumb1.Image = image;
				thumb1.SizeMode = PictureBoxSizeMode.StretchImage;
				thumb1.BorderStyle = BorderStyle.FixedSingle;
				Panel1.Controls.Add(thumb1);

				if (dual)
				{
					thumb1.Size = new Size(32, 32);
					thumb1.Location = new Point(0, 0);
					thumb1.SendToBack();
				}
				else
					thumb1.Size = new Size(48, 48);
			});
		}

		/// <summary>A callback to receive the "to" small image.</summary>
		/// <param name="image">The received image.</param>
		void ImageAsync_ToThumb(Image image)
		{
			Utils.InvokeControl(this, delegate()
			{
				thumb2 = new PictureBox();
				thumb2.Image = image;
				thumb2.SizeMode = PictureBoxSizeMode.StretchImage;
				thumb2.BorderStyle = BorderStyle.FixedSingle;

				thumb2.Size = new Size(32, 32);
				thumb2.Location = new Point(16, 16);
				Panel1.Controls.Add(thumb2);
				thumb2.BringToFront();
			});
		}

		/// <summary>A callback to receive the "from" large image.</summary>
		/// <param name="image">The received image.</param>
		void ImageAsync_FromLarge(Image image)
		{
			Utils.InvokeControl(this, delegate()
			{
				pic1 = pic1 ?? new ProfilePicForm(image);
				if (hovered)
				{
					pic1.Show();
					Point spos = new Point(48 - pic1.Width, 0);
					spos = PointToScreen(spos);
					pic1.SetDesktopLocation(spos.X, spos.Y);
				}
			});
		}

		/// <summary>A callback to receive the "to" large image.</summary>
		/// <param name="image">The received image.</param>
		void ImageAsync_ToLarge(Image image)
		{
			Utils.InvokeControl(this, delegate()
			{
				pic2 = pic2 ?? new ProfilePicForm(image);
				if (hovered)
				{
					pic2.Show();
					Point spos = new Point(Width, 0);
					spos = PointToScreen(spos);
					pic2.SetDesktopLocation(spos.X, spos.Y);
				}
			});
		}

		/// <summary>Fired when the cursor makes the row expand.</summary>
		/// <param name="sender">The event sender.</param>
		/// <param name="e">The event parameters.</param>
		void HoverOn(object sender, EventArgs e)
		{
			hovered = true;
			rtf.Expand();
			if (msg.From != null)
				msg.From.LoadImageAsync(true, ImageAsync_FromLarge);
			if (msg.To != null)
				msg.To.LoadImageAsync(true, ImageAsync_ToLarge);
		}

		/// <summary>Fired when the cursor makes the row contract.</summary>
		/// <param name="sender">The event sender.</param>
		/// <param name="e">The event parameters.</param>
		void HoverOff(object sender, EventArgs e)
		{
			hovered = false;
			rtf.Contract();
			if (pic1 != null)
				pic1.Hide();
			if (pic2 != null)
				pic2.Hide();
		}
	}
}
